package com.roc.admin.infrastructure.repository.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.roc.admin.domain.entity.Menu;
import com.roc.admin.domain.repository.MenuRepository;
import com.roc.admin.infrastructure.mapper.MenuMapper;
import com.roc.admin.infrastructure.persistence.MenuPO;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Repository;

import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 菜单仓储实现类
 */
@Repository
public class MenuRepositoryImpl implements MenuRepository {

    private final MenuMapper menuMapper;

    public MenuRepositoryImpl(MenuMapper menuMapper) {
        this.menuMapper = menuMapper;
    }

    @Override
    public Menu save(Menu menu) {
        MenuPO menuPO = toMenuPO(menu);
        if (menuPO.getId() == null) {
            menuMapper.insert(menuPO);
        } else {
            menuMapper.updateById(menuPO);
        }
        return toMenu(menuPO);
    }

    @Override
    public Optional<Menu> findById(Long id) {
        MenuPO menuPO = menuMapper.selectById(id);
        return Optional.ofNullable(menuPO).map(this::toMenu);
    }

    @Override
    public List<Menu> findAll() {
        List<MenuPO> menuPOList = menuMapper.selectList(null);
        return menuPOList.stream().map(this::toMenu).collect(Collectors.toList());
    }

    @Override
    public List<Menu> findByParentId(Long parentId) {
        LambdaQueryWrapper<MenuPO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(MenuPO::getParentId, parentId);
        queryWrapper.orderByAsc(MenuPO::getSort);
        List<MenuPO> menuPOList = menuMapper.selectList(queryWrapper);
        return menuPOList.stream().map(this::toMenu).collect(Collectors.toList());
    }

    @Override
    public List<Menu> findByRoleId(Long roleId) {
        List<MenuPO> menuPOList = menuMapper.selectMenusByRoleId(roleId);
        return menuPOList.stream().map(this::toMenu).collect(Collectors.toList());
    }

    @Override
    public List<Menu> findByUserId(Long userId) {
        List<MenuPO> menuPOList = menuMapper.selectMenusByUserId(userId);
        return menuPOList.stream().map(this::toMenu).collect(Collectors.toList());
    }

    @Override
    public void deleteById(Long id) {
        menuMapper.deleteById(id);
    }

    /**
     * 将菜单实体转换为持久化对象
     *
     * @param menu 菜单实体
     * @return 菜单持久化对象
     */
    private MenuPO toMenuPO(Menu menu) {
        if (menu == null) {
            return null;
        }
        MenuPO menuPO = new MenuPO();
        BeanUtils.copyProperties(menu, menuPO);
        return menuPO;
    }

    /**
     * 将持久化对象转换为菜单实体
     *
     * @param menuPO 菜单持久化对象
     * @return 菜单实体
     */
    private Menu toMenu(MenuPO menuPO) {
        if (menuPO == null) {
            return null;
        }
        Menu menu = new Menu();
        BeanUtils.copyProperties(menuPO, menu);
        return menu;
    }
}
